package nsh.cl.nd.khtn.mazedash;

import nsh.cl.nd.khtn.mazedash.entity.Cell;
import nsh.cl.nd.khtn.mazedash.entity.CellType;
import nsh.cl.nd.khtn.mazedash.entity.GUICell;

public class MapManager {
	
	public static int WALL = CellType.WALL.getValue();
	public static int PATH = CellType.PATH.getValue();
	public static int START = 2;
	public static int CURRENT_POSITION = CellType.PLAYER.getValue();
	public static int END = 4;
	
	public static int[][] DEMO_MAP_1 = new int[][]{
		{ 0, 0, 0, 0, 0, 0, 0 }, 
		{ 0, 1, 1, 1, 0, 1, 0 },
		{ 0, 1, 1, 1, 1, 1, 0 },
		{ 0, 1, 1, 0, 4, 1, 0 },
		{ 0, 2, 1, 1, 1, 0, 0 },
		{ 0, 0, 0, 0, 0, 0, 0 }
	};
	
	// Map[row][col]
	private int rowMainChar = -1;
	private int colMainChar = -1;
	private Cell[][] guiMap;
	private GUICell cell;
	
	public MapManager() {
	}
	
	public MapManager(GUICell cell) {
		this.cell = cell;
	}

	public void loadDataMap(int level) {
		int[][] map = DEMO_MAP_1.clone();
		guiMap = new Cell[map.length][map[0].length];
		for (int i = 0; i < guiMap.length; i++) {
			for (int j = 0; j < guiMap[i].length; j++) {
				GUICell guiCell = new GUICell(0, 0, cell.getTextureRegion(), cell.getVertexBufferObjectManager());
				guiMap[i][j] = new Cell(map[i][j], guiCell);
			}
		}
		findStartCellInMap();
		setPositionForAllCells();
	}
	
	private void setPositionForAllCells() {
		for (int i = 0; i < guiMap.length; i++) {
			for (int j = 0; j < guiMap[i].length; j++) {
				guiMap[i][j].getGuiCell().setPosition(j * GameConstant.CELL_HEIGHT, i * GameConstant.CELL_WIDTH);
			}
		}
	}

	private void findStartCellInMap() {
		for (int i = 0; i < guiMap.length; i++) {
			for (int j = 0; j < guiMap[i].length; j++) {
				if (guiMap[i][j].getData() == START) {
					rowMainChar = i;
					colMainChar = j;
					guiMap[i][j].setData(CURRENT_POSITION);
					break;
				}
			}
		}
	}
	
	public void moveLeft() {
		if (colMainChar - 1 < 0) {
			return;
		}
		if (!canMove(guiMap[rowMainChar][colMainChar - 1].getData())) {
			return;
		}
		stepFromCell();
		colMainChar--;
		stepToCell();
		
		moveLeft();
	}
	
	public void moveRight() {
		if (colMainChar + 1 > guiMap[rowMainChar].length) {
			return;
		}
		if (!canMove(guiMap[rowMainChar][colMainChar + 1].getData())) {
			return;
		}
		stepFromCell();
		colMainChar++;
		stepToCell();
		
		moveRight();
	}
	
	public void moveUp() {
		if (rowMainChar - 1 < 0) {
			return;
		}
		if (!canMove(guiMap[rowMainChar - 1][colMainChar].getData())) {
			return;
		}
		stepFromCell();
		rowMainChar--;
		stepToCell();
		
		moveUp();
	}
	
	public void moveDown() {
		if (rowMainChar + 1 > guiMap.length) {
			return;
		}
		if (!canMove(guiMap[rowMainChar + 1][colMainChar].getData())) {
			return;
		}
		stepFromCell();
		rowMainChar++;
		stepToCell();
		
		moveDown();
	}

	private boolean canMove(int cellValue) {
		boolean canMone = cellValue == PATH || cellValue == END;
		if (!canMone) {
			//RootGameActivity.getInstance().getCamera().shake(0.2f, 1.5f);
		}
		return canMone;
	}
	
	private void stepToCell() {
		if (guiMap[rowMainChar][colMainChar].getData() == END) {
			System.out.println("WIN");
			RootGameActivity.getInstance().getScreenManager().getPlayScene().gameOver();
		}
		guiMap[rowMainChar][colMainChar].setData(CURRENT_POSITION);
	}

	private void stepFromCell() {
		guiMap[rowMainChar][colMainChar].setData(PATH);
	}

	public String printMap() {
		StringBuilder string = new StringBuilder();
		for (int i = 0; i < guiMap.length; i++) {
			for (int j = 0; j < guiMap[i].length; j++) {
				if (i == rowMainChar && j == colMainChar) {
					string.append("# ");
				} else {
					string.append(guiMap[i][j].getData() + " ");
				}
			}
			string.append("\n");
		}
		System.out.println(string);
		return string.toString();
	}
	
	//TODO AHO TEST ONLY
	public static void main(String[] args) {
		MapManager mapManager = new MapManager();
		mapManager.loadDataMap(1);
		mapManager.findStartCellInMap();
		mapManager.printMap();
		
		mapManager.moveUp();
		mapManager.moveRight();
		mapManager.moveDown();
		mapManager.moveLeft();
	}

	public Cell[][] getGuiMap() {
		return guiMap;
	}

}